#include <iostream>
#include <string>
#include "Reactor.hpp"
#include "Listener.hpp"
#include "Channel.hpp"
#include "Log.hpp"
#include "Common.hpp"
#include "Protocol.hpp"
#include "NetCal.hpp"

static void Usage(std::string proc)
{
    std::cerr << "Usage: " << proc << " port" << std::endl;
}

//./server port
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(USAGE_ERR);
    }

    LogModule::ConsoleLogStrategy();
    uint16_t port = std::stoi(argv[1]);
    // 构建一个业务模块
    std::shared_ptr<Cal> cal = std::make_shared<Cal>();

    // 构建协议对象
    std::shared_ptr<Protocol> protocol = std::make_shared<Protocol>([&cal](Request &req) -> Response
                                                                    { return cal->Execute(req); });

    // 构建Listener对象
	
	//Listener是负责监听端口、接受客户端新连接的组件，这里用端口号初始化，并向上转型为Connection基类指针（多态设计，统一管理不同类型的连接）。
	//RegisterHandler注册了一个 “数据处理回调函数”（lambda 表达式），该函数是协议层与网络层的桥梁，作用是：
	//从输入缓冲区inbuffer中解码出完整的数据包（通过protocol->Decode）。
	//对每个完整数据包调用protocol->Execute处理（内部会触发前面注册的业务处理器cal->Execute）。
	//将处理结果（响应数据）拼接成字符串返回，最终会被发送给客户端。
	//其中while(true)循环确保一次性处理inbuffer中所有完整的数据包（解决粘包问题：可能一次收到多个报文），
	//未处理完的不完整数据会留在inbuffer中，等待下次数据到来后继续处理。
    std::shared_ptr<Connection> conn = std::make_shared<Listener>(port);
    conn->RegisterHandler([&protocol](std::string &inbuffer) -> std::string { // 这个匿名函数就是要被Channel
        LOG(LogLevel::DEBUG) << "进入到匿名函数中...";
        std::string response_str;
        while (true)
        {
            std::string package;
            if (!protocol->Decode(inbuffer, &package))
                break;
            // 我敢保证，我的packge一定是一个完整的请求，是字节流的
            response_str += protocol->Execute(package);
        }
        LOG(LogLevel::DEBUG) << "结束匿名函数中...: " << response_str;
        return response_str;
    });

    // 构建一个reactor模块
    std::unique_ptr<Reactor> R = std::make_unique<Reactor>();
    R->AddConnection(conn);

    R->Loop();

    return 0;
}